package com.design.springboot.booksharing.interceptor;

import com.design.springboot.booksharing.annotation.AllowNoToken;
import com.design.springboot.booksharing.bean.ActiveUser;
import com.design.springboot.booksharing.constant.SystemConstant;
import com.design.springboot.booksharing.enums.ApiResultCodeEnum;
import com.design.springboot.booksharing.exception.ApiException;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;

/**
 * 认证拦截器
 */
@Component
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        Method method = ((HandlerMethod) handler).getMethod();

        boolean allowNoTokenClass = method.getDeclaringClass().isAnnotationPresent(AllowNoToken.class);
        boolean allowNoTokenMethod = method.isAnnotationPresent(AllowNoToken.class);
        if (allowNoTokenClass || allowNoTokenMethod) {
            return true;
        }

        HttpSession session = request.getSession();
        ActiveUser activeUser = (ActiveUser) session.getAttribute(SystemConstant.ACTIVE_USER);
        if (activeUser != null) {
            return true;
        }

        throw new ApiException(ApiResultCodeEnum.TOKEN_NULL);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}
